package io.kiki.sba.registry.server.metadata.bootstrap.config;


import io.kiki.sba.registry.net.NetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;


public abstract class AbstractNodeConfigBean implements NodeConfig {

    private static final Logger logger = LoggerFactory.getLogger(AbstractNodeConfigBean.class);
    private final Map<String, String> dataCenterMetaIPCache = new HashMap<>();
    protected Map<String, List<String>> dataCenterToIpList;

    @Override
    public Map<String, List<String>> getDataCenterToIpList() {
        if (dataCenterToIpList == null || dataCenterToIpList.isEmpty()) {
            dataCenterToIpList = convertToIP(getMetaNode());
        }
        return dataCenterToIpList;
    }

    private Map<String /*dataCenterId*/, List<String>> convertToIP(Map<String, Collection<String>> map) {

        Map<String, List<String>> hashMap = new HashMap<>();
        try {

            if (map != null) {
                map.forEach((dataCenter, collection) -> {
                    if (collection != null) {
                        List<String> ipList = new ArrayList<>();
                        collection.forEach((domain) -> {
                            if (domain != null) {
                                String ip = NetUtil.getIPAddressFromDomain(domain);
                                if (ip == null) {
                                    logger.error("Node config convert domain {} error!", domain);
                                    throw new RuntimeException("Node config convert domain {" + domain + "} error!");
                                }
                                ipList.add(ip);
                            }
                        });
                        hashMap.put(dataCenter, ipList);
                    }
                });
            }
        } catch (Exception e) {
            logger.error("Node config convert domain error!", e);
            throw new RuntimeException("Node config convert domain error!", e);
        }
        return hashMap;
    }

    @Override
    public String getCentralControlDataCenter(String metaIpAddress) {
        if (metaIpAddress == null || metaIpAddress.isEmpty()) {
            logger.error("IpAddress:" + metaIpAddress + " cannot be null!");
            return null;
        }

        String dataCenterRet = dataCenterMetaIPCache.get(metaIpAddress);

        if (dataCenterRet == null || dataCenterRet.isEmpty()) {
            Map<String, List<String>> dataCenterToIpList1 = getDataCenterToIpList();
            AtomicReference<String> atomicReference = new AtomicReference<>();
            dataCenterToIpList1.forEach((dataCenter, list) -> {
                if (list.contains(metaIpAddress)) {
                    atomicReference.set(dataCenter);
                }
            });

            dataCenterRet = atomicReference.get();
        }
        return dataCenterRet;
    }

    @Override
    public Set<String> getDataCenterMetaServers(String dataCenterIn) {
        Map<String, List<String>> map = getDataCenterToIpList();
        Set<String> set = new HashSet<>();
        if (map != null && map.size() > 0) {
            Collection<String> list = map.get(dataCenterIn);
            if (list != null) {
                set.addAll(list);
            }
        }
        return set;
    }
}
